package com.hserver.docker.service.impl;

import com.fasterxml.jackson.databind.JsonNode;
import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.command.CreateContainerResponse;
import com.github.dockerjava.api.model.*;
import com.hserver.docker.bean.Registry;
import com.hserver.docker.dao.RegistryMapper;
import com.hserver.docker.service.RegistryService;
import com.hserver.docker.utils.DockerUtil;
import org.jsoup.Jsoup;
import cn.hserver.core.ioc.annotation.Autowired;
import cn.hserver.core.ioc.annotation.Bean;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;

import static cn.hserver.plugin.web.context.WebConstConfig.JSON;
import static com.github.dockerjava.api.model.ExposedPort.tcp;
import static com.github.dockerjava.api.model.HostConfig.newHostConfig;

/**
 * @author hxm
 */
@Bean
public class RegistryServiceImpl implements RegistryService {

    @Autowired
    private RegistryMapper registryMapper;

    private static final String DEFAULT_IMAGE = "registry:latest";

    @Override
    public void add(Registry registry) {
        registryMapper.delete();
        registryMapper.insert(registry);
        //创建网络服务
        DockerClient docker = DockerUtil.getDocker();
        try {
            boolean b = docker.pullImageCmd(DEFAULT_IMAGE)
                    .start()
                    .awaitCompletion(30, TimeUnit.SECONDS);
            if (b) {
                //端口
                Ports portBindings = new Ports();
                List<ExposedPort> exposedPorts = new ArrayList<>();
                int i = Integer.parseInt(registry.getPort());
                //容器的端口
                //容器端口
                ExposedPort tcp = tcp(5000);
                exposedPorts.add(tcp);
                //主机端口
                portBindings.bind(tcp, Ports.Binding.bindPort(i));
                List<Bind> volumes = new ArrayList<>();
                //主机地址,容器地址
                volumes.add(new Bind(registry.getPath(), new Volume("/var/lib/registry")));
                CreateContainerResponse exec = docker.createContainerCmd(DEFAULT_IMAGE).withHostConfig(newHostConfig()
                        .withPortBindings(portBindings)
                        .withRestartPolicy(RestartPolicy.alwaysRestart())
                        .withBinds(volumes)).exec();
                String id = exec.getId();
                docker.startContainerCmd(id).exec();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            try {
                docker.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public List<String> data() {
        List<String> data = new ArrayList<>();
        List<Registry> select = registryMapper.createLambdaQuery().select();
        if (select.size() == 1) {
            Registry registry = select.get(0);
            String host = registry.getHost();
            try {
                String text = Jsoup.connect("http://"+host + ":" + registry.getPort() + "/v2/_catalog").ignoreContentType(true).get().body().text();
                JsonNode repositories = JSON.readTree(text).get("repositories");
                if (repositories.isArray()) {
                    for (JsonNode objNode : repositories) {
                        data.add(objNode.asText());
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
        return data;
    }

    @Override
    public Registry getRegistry() {
        List<Registry> select = registryMapper.createLambdaQuery().select();
        if (select.size() == 1) {
            return select.get(0);
        }
        return null;
    }

}
